home *** CD-ROM | disk | FTP | other *** search
Text File | 2007-10-18 | 59.9 KB | 1,854 lines |
- // vim: ts=2 sw=2 expandtab cindent
- //
- // BEGIN FLOCK GPL
- //
- // Copyright Flock Inc. 2005-2007
- // http://flock.com
- //
- // This file may be used under the terms of of the
- // GNU General Public License Version 2 or later (the "GPL"),
- // http://www.gnu.org/licenses/gpl.html
- //
- // Software distributed under the License is distributed on an "AS IS" basis,
- // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- // for the specific language governing rights and limitations under the
- // License.
- //
- // END FLOCK GPL
-
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- const Cr = Components.results;
- const Cu = Components.utils;
-
- const CLASS_ID = Components.ID("{8DAEC4A0-8623-11DB-B606-0800200C9A66}");
- const CLASS_NAME = "piczo";
- const CLASS_DESC = "Flock Piczo Service";
- const CONTRACT_ID = "@flock.com/people/piczo;1";
- const FLOCK_PHOTO_ALBUM_CONTRACTID = "@flock.com/photo-album;1";
- const FLOCK_PHOTO_ACCOUNT_CONTRACTID = "@flock.com/photo-account;1";
- const SERVICE_ENABLED_PREF = "flock.service.piczo.enabled";
- const CATEGORY_COMPONENT_NAME = "Piczo JS Component"
- const CATEGORY_ENTRY_NAME = "piczo"
-
- var gCompTK;
- function getCompTK() {
- if (!gCompTK) {
- gCompTK = Components.classes["@flock.com/singleton;1"]
- .getService(Components.interfaces.flockISingleton)
- .getSingleton("chrome://browser/content/flock/services/common/load-compTK.js")
- .wrappedJSObject;
- }
- return gCompTK;
- }
-
- var gTimers = []; // For use with the scheduler
-
- // String defaults... may be updated later through Web Detective
- var gStrings = {
- "domains": "piczo.com",
- "sessioncookie": "JSESSIONID",
- "mainpage": "http://www.piczo.com/",
- "favicon": "http://www.piczo.com/favicon.ico",
- "userlogin": "http://www.piczo.com/",
- "userprofile": "http://%accountid%.piczo.com/",
- "api-agent-string": "Flock",
- "api-setup-URL": "http://api.piczo.com/api-1/setup?api-agent=%agent%",
- "api-login-URL": "http://api.piczo.com/api-1/login",
- "api-friends-URL": "http://api.piczo.com/api-1/friends",
- };
-
- var gAPI = null;
- var gSVC = null;
-
- function loadLibraryFromSpec(aSpec)
- {
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Components.interfaces.mozIJSSubScriptLoader);
- loader.loadSubScript(aSpec);
- }
-
- loadLibraryFromSpec("chrome://flock/content/common/flocksafe.js");
- loadLibraryFromSpec("chrome://browser/content/flock/photo/photoAPI.js");
-
- // ==============================================
- // ========== BEGIN piczoService class ==========
- // ==============================================
- var _logger = null;
- function piczoService()
- {
- _logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger);
- _logger.init("piczo");
- _logger.info("CONSTRUCTOR");
-
- this.obs = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- this.acUtils = Components.classes["@flock.com/account-utils;1"]
- .getService(Components.interfaces.flockIAccountUtils);
- this.url = gStrings["mainpage"];
- this.mIsInitialized = false;
- this._ctk = {
- interfaces: [
- "nsISupports",
- "nsIClassInfo",
- "nsISupportsCString",
- "nsIObserver",
- "flockIWebService",
- "flockIManageableWebService",
- "flockIPollingService",
- "flockIAuthenticateNewAccount",
- "flockIMediaWebService",
- "flockIMediaUploadAccount",
- "flockIPiczoService"
- ],
- shortName: "piczo",
- fullName: "Piczo",
- description: CLASS_DESC,
- domains: gStrings["domains"],
- favicon: gStrings["favicon"],
- CID: CLASS_ID,
- contractID: CONTRACT_ID,
- accountClass: piczoAccount,
- };
- }
-
- // BEGIN flockIMediaWebService interface
- function createEnum( array ) {
- return {
- QueryInterface: function (iid) {
- if (iid.equals(Ci.nsISimpleEnumerator)) {
- return this;
- }
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- hasMoreElements: function() {
- return (array.length > 0);
- },
- getNext: function() {
- return array.shift();
- }
- }
- }
-
- function piczoPhoto() {
-
- }
-
- piczoPhoto.prototype= {
- id: "",
- thumbnail: "",
- webPageUrl: "",
- midSizePhoto: "",
- largeSizePhoto: "",
- title: "",
- username: "",
- userid: "",
- is_public: true,
- is_video: false,
- svcShortName: 'piczo',
- buildTooltip: function( ) {
- // do we have to use document from the window to ceate elements? -- ja
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (!win) {
- return null;
- }
-
- var hbox = win.document.createElement('hbox');
- var img = win.document.createElement('image');
- img.setAttribute('src', this.icon );
- hbox.appendChild(img);
- var box = win.document.createElement('vbox');
- box.setAttribute('style', 'max-width: 250px');
- var title = win.document.createElement('label');
- title.setAttribute('value', this.title );
- title.setAttribute('crop', 'end');
- box.appendChild(title);
- var lbl = win.document.createElement('label');
- lbl.setAttribute('value', this.username );
- lbl.setAttribute('class', 'user');
- box.appendChild(lbl);
- hbox.appendChild(box)
-
- var vbox = win.document.createElement('vbox');
- var cbox = win.document.createElement('hbox');
- var largeImg = win.document.createElement('image');
- largeImg.setAttribute('src', this.midSizePhoto);
- largeImg.setAttribute('style', 'margin-bottom: 2px;');
- var spacer = win.document.createElement('spacer');
- spacer.setAttribute('flex', '1');
- cbox.appendChild(largeImg);
- cbox.appendChild(spacer);
- vbox.appendChild(cbox);
- vbox.appendChild(hbox);
-
- return vbox;
- },
- buildHTML: function( ) {
- return '<a title="'+this.title+'" href="'+this.webPageUrl+'"><img src="'+this.midSizePhoto+'" border="0" /></a>';
- },
- buildLargeHTML: function( ) {
- return '<a title="'+this.title+'" href="'+this.webPageUrl+'"><img src="'+this.largeSizePhoto+'" border="0" /></a>';
- },
- buildBBCode: function ( ) {
- return '[url=' + this.webPageUrl + '][img]'+ this.largeSizePhoto +'[/img][/url]';
- },
- QueryInterface: function(iid) {
- if (!iid.equals(Ci.nsISupports) && !iid.equals(Ci.flockIPhoto)) {
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- return this;
- }
- };
-
- piczoService.prototype.iconUrl = gStrings["favicon"];
-
- piczoService.prototype.handleDragDrop =
- function piczoService_handleDragDrop (aURL, aXLoc, aYLoc) {
- return gAPI.handleDragDrop(aURL, aXLoc, aYLoc);
- }
-
- piczoService.prototype.supportsFeature =
- function piczoService_supportsFeature(aFeature)
- {
- var supports = {};
- supports.tags = false;
- supports.title = false;
- supports.notes = false;
- supports.fileName = false;
- supports.contacts = true;
- supports.privacy = false;
- supports.albumCreation = false;
- return (supports[aFeature] == true);
- }
-
- piczoService.prototype.login =
- function piczoService_login(aAccountURN, aListener) {
- _logger.info("piczoService.login()");
- }
-
- piczoService.prototype.__defineGetter__('isLoggedIn', function () { return gAPI.isLoggedIn(); })
-
- piczoService.prototype.getAuthPerson = function () {
- try {
- var session = gAPI.getAuthUser();
- var person = {};
- person.id = session.userGUID;
- person.fullname = session.username;
- person.username = session.username;
- person.service = this;
- return person;
- }
- catch(e) {
- return null;
- }
- }
-
- piczoService.prototype.findByUsername =
- function piczoService_findByUsername(aListener, aUsername) {
- // Needed to have observer call .search();
- aListener.onError(null);
- }
-
- piczoService.prototype.serviceName = "Piczo";
- piczoService.prototype.shortName = "piczo";
-
- piczoService.prototype.search =
- function piczoService_search(aListener, aQueryString, aCount, aPage)
- {
- // Piczo doesn't support paging
- if(aPage > 1) return;
-
- // XXX: TODO
- _logger.debug("piczoService_search: " + aQueryString);
-
- var aQuery = new queryHelper(aQueryString);
- var myListener = {
- onSuccess: function (enumResults, status) {
- aListener.onSearchResult(enumResults);
- },
- onError: function (aFlockError) {
- //_logger.info("piczoService_search ERROR: " + aFlockError.serviceErrorString + "\n");
- aListener.onError(aFlockError);
- }
- }
-
- var params = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- params.setPropertyAsAString("subj_id", aQuery.search);
- params.setPropertyAsAString("albumlabel", aQuery.albumlabel);
- if (gAPI.isLoggedIn())
- {
- gAPI.getPhotos(myListener, params);
- } else {
- _logger.info("piczoService wasnt logged in....");
- // We are not logged in, force user to log in now.
- var aError = Cc['@flock.com/error;1'].createInstance(Ci.flockIError);
- aError.errorCode = Ci.flockIError.PHOTOSERVICE_USER_NOT_LOGGED_IN;
- aListener.onError(aError);
- }
- }
-
- piczoService.prototype.cancelUpload =
- function piczoService_cancelUpload() {
- try {
- _logger.info("Cancelling upload...");
- gAPI.uploader.req.abort();
- } catch (e) {
- _logger.info("Error cancelling upload.");
- }
- }
-
- piczoService.prototype.upload =
- function piczoService_upload(aListener, aUpload, aFile) {
- _logger.info("piczoService_upload");
-
- var params = {};
- /*params.title = aUpload.title;
- params.description = aUpload.description;
- params.is_family = aUpload.is_family;
- params.is_friend = aUpload.is_friend;
- params.is_public = aUpload.is_public;
- params.async = "1";
- params.tags = aUpload.tags;
- */
- gAPI.upload(aListener, aFile, params, aUpload);
- }
-
- piczoService.prototype.getAlbums =
- function piczoService_getAlbums(aListener, aUserID) {
- _logger.info("[piczoAPI].getAlbum call...");
- var myListener = {
- onResult: function (enumResults, status) {
- _logger.info("[piczoAPI].getAlbums onResult!");
- aListener.onGetAlbumsResult(enumResults);
- },
- onError: function (flockError) {
- _logger.info("[piczoAPI].getAlbums onError!" + flockError.errorString);
- //aListener.onError("Unable to get albums: " + flockError.errorString);
- }
- }
-
- // NOTE: the uid needs to be changed to the uid of aUsername for general user searches
- gAPI.getAlbums(myListener, aUserID);
- }
-
- /**
- * getAlbumsForUpload
- * @see flockIMediaWebService#getAlbumsForUpload
- */
- piczoService.prototype.getAlbumsForUpload =
- function piczoService_getAlbumsForUpload(aListener, aUsername) {
- // Needs specific implementation for uploading albums
- _logger.info("[piczoAPI].getAlbumsForUpload call...");
- var myListener = {
- onResult: function (enumResults, status) {
- _logger.info("[piczoAPI].getAlbumsForUpload onResult!");
- aListener.onGetAlbumsResult(enumResults);
- },
- onError: function (flockError) {
- _logger.info("[piczoAPI].getAlbumsForUpload onError!" + flockError.errorString);
- }
- }
-
- // NOTE: the uid needs to be changed to the uid of aUsername for general user searches
- gAPI.getAlbumsForUpload(myListener, aUsername);
- }
-
- piczoService.prototype.getAccountStatus =
- function piczoService_getAccountStatus(aListener) {
- var inst = this;
-
- var listener = {
- onSuccess: function (aXML) {
- _logger.info("piczoService: getAccountStatus Success!");
- var result = Cc["@mozilla.org/hash-property-bag;1"]
- .createInstance(Ci.nsIWritablePropertyBag2);
- //var username = aXML.getElementsByTagName('username')[0].firstChild.nodeValue;
- //var bandwidth = aXML.getElementsByTagName('bandwidth')[0];
- //var maxFileSize = aXML.getElementsByTagName('filesize')[0];
- //var isPro = aXML.getElementsByTagName('user')[0].getAttribute('ispro');
- result.setPropertyAsAString("maxSpace", "500000");
- result.setPropertyAsAString("usedSpace", "0");
- result.setPropertyAsAString("maxFileSize", "500000");
- result.setPropertyAsAString("usageUnits", "bytes");
- result.setPropertyAsBool("isPremium", false);
- aListener.onSuccess(result, "");
- },
- onError: function (aError) {
- aListener.onError(aError);
- _logger.info("piczoService: getAccountStatus ERROR");
- }
- }
-
- gAPI.getAccountStatus(listener);
- }
-
- piczoService.prototype.call =
- function piczoService_call(aListener, aMethod, aDictionary, aAuth)
- {
- _logger.info("piczoService_call");
- return this.doCall(aListener, aMethod, aDictionary, aAuth);
- }
-
- piczoService.prototype.createAlbum =
- function piczoService_createAlbum(aListener, aPath)
- {
- // XXX: TODO
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- }
-
- piczoService.prototype.supportsSearch =
- function piczoService_supportsSearch(aQueryString ) {
- _logger.debug("piczoService_supportsSearch: " + aQueryString);
- return false;
- }
-
-
- // BEGIN flockIWebService interface
- piczoService.prototype.addAccountById =
- function piczoService_addAccountById(aAccountID, aIsTransient, aListener)
- {
- _logger.info("{flockIWebService}.addAccountById('" + aAccountID + "', " + aIsTransient + ")");
- var accountURN = "urn:flock:piczo:account:"+aAccountID;
- var c_acct = new this._coop.Account(
- accountURN, {
- name: aAccountID,
- accountId: aAccountID,
- serviceId: CONTRACT_ID,
- service: this.c_svc,
- favicon: gStrings["favicon"],
- URL: gStrings["userprofile"].replace("%accountid%", aAccountID),
- isTransient: aIsTransient,
- isPollable: true,
- }
- );
- this._coop.accounts_root.children.add(c_acct);
-
- // Instanciate account component
- var acct = this.getAccount(c_acct.id());
- if (aListener) aListener.onSuccess(acct, "addAccount");
- return acct;
- }
- // END flockIWebService interface
-
-
- piczoService.prototype.authenticateNewAccount =
- function flickrService_authenticateNewAccount(aListener)
- {
- _logger.info("{flockIAuthenticateNewAccount}.authenticateNewAccount(aListener)");
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- win.openUILinkIn(this.url, "tab");
- }
-
-
- // BEGIN flockIMediaWebService interface
- piczoService.prototype.decorateForMedia =
- function piczoService_decorateForMedia(aDocument)
- {
- _logger.info("{flockIMediaWebService}.decorateForMedia()");
- // XXX TODO FIXME: implement
- }
- // END flockIMediaWebService interface
-
-
- // BEGIN flockIManageableWebService interface
- piczoService.prototype.getAccountIDFromDocument =
- function piczoService_getAccountIDFromDocument(aDocument)
- {
- _logger.info("{flockIManageableWebService}.getAccountIDFromDocument()");
- aDocument.QueryInterface(Components.interfaces.nsIDOMHTMLDocument);
- var acctID;
- var results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- if (this.webDetective.detect("piczo", "accountinfo", aDocument, results)) {
- // If this page has the user GUID on it, then we can do a Coop lookup
- // for accounts with that GUID
- acctID = this._getAccountIDFromGUID(results.getPropertyAsAString("piczo_guid"));
- }
- if (!acctID) {
- // We haven't determined the account yet.
- // Since some login landing pages don't have account info on them that we
- // can detect, we can try seeing if there's a session cookie stored as a
- // temp password entry. (This is a hack.)
- var sessionValue = this.acUtils.getCookie("http://piczo.com",
- gStrings["sessioncookie"]);
- if (!sessionValue) {
- sessionValue = this.acUtils.getCookie("http://www.piczo.com",
- gStrings["sessioncookie"]);
- }
- var pw = this.acUtils.getTempPassword("piczo:session:"+sessionValue);
- if (pw) {
- _logger.debug("Sneaky! Got acctID from a temp password associated with session cookie!");
- acctID = pw.user;
- }
- }
- return acctID;
- }
-
- piczoService.prototype.getCredentialsFromForm =
- function piczoService_getCredentialsFromForm(aForm)
- {
- // Convenience method for Web Detective calls
- var inst = this;
- var detectForm = function piczo_detectForm(aType, aResults) {
- return inst.webDetective.detectForm("piczo", aType, aForm, aResults);
- };
-
- // Try to detect login, then signup, then changepassword, in that order
- var formType = "login";
- var results = getCompTK().newResults();
- if (!detectForm(formType, results)) {
- // No login detected, so check for signup
- formType = "signup";
- results = getCompTK().newResults();
- if (!detectForm(formType, results)) {
- // No signup detected, so try changepassword
- formType = "changepassword";
- results = getCompTK().newResults();
- if (!detectForm(formType, results)) {
- results = null;
- }
- }
- }
-
- if (results) {
- // We were able to get results from at least one of the checks above
- var pw = {
- QueryInterface: function(aIID) {
- if (!aIID.equals(Components.interfaces.nsISupports) &&
- !aIID.equals(Components.interfaces.nsIPassword) &&
- !aIID.equals(Components.interfaces.flockIPassword))
- {
- throw Components.interfaces.NS_ERROR_NO_INTERFACE;
- }
- return this;
- },
- user: results.getPropertyAsAString("username"),
- password: results.getPropertyAsAString("password"),
- host: null,
- formType: formType
- };
-
- // Doing a bit of a hack here...
- // Since the Piczo login landing page doesn't always reveal which
- // account is logged in, we will need to look at the session cookie and
- // see if its the same as what it was when the user last logged in. So
- // at this point we're just storing the account username as a temp
- // password entry associated with the session cookie token.
- var sessionValue = this.acUtils.getCookie("http://piczo.com",
- gStrings["sessioncookie"]);
- if (!sessionValue) {
- sessionValue = this.acUtils.getCookie("http://www.piczo.com",
- gStrings["sessioncookie"]);
- }
- this.acUtils.clearTempPassword("piczo:session:" + sessionValue);
- this.acUtils.setTempPassword("piczo:session:" + sessionValue, pw.user, "",
- formType);
- return pw;
- }
- return null;
- }
-
- piczoService.prototype._getAccountIDFromGUID =
- function piczoService__getAccountIDFromGUID(aGUID)
- {
- _logger.info("_getAccountIDFromGUID('" + aGUID + "')");
- var accts = this._coop.Account.find({serviceId: CONTRACT_ID, piczo_guid: aGUID});
- return (accts.length) ? accts[0].accountId : null;
- }
-
- piczoService.prototype.updateAccountStatusFromDocument =
- function piczoService_updateAccountStatusFromDocument(aDocument)
- {
- _logger.info("{flockIManageableWebService}.updateAccountStatusFromDocument()");
- if (this.webDetective.detect("piczo", "loggedout", aDocument, null)) {
- this.acUtils.markAllAccountsAsLoggedOut(CONTRACT_ID);
- } else if (this.webDetective.detect("piczo", "loggedin", aDocument, null)) {
- var results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- var accountID = null;
- var profileURL = null;
- if (this.webDetective.detect("piczo", "accountinfo", aDocument, results)) {
- var guid = results.getPropertyAsAString("piczo_guid");
- accountID = this._getAccountIDFromGUID(guid);
- // The profileURL is not always returned, so we need to test for it within
- // a try/catch -> getPropertyAsAString will throw if it does not find the
- // given property.
- try {
- profileURL = results.getPropertyAsAString("profileURL");
- } catch (ex) {
- // Didn't find profileURL. Just carry on.
- _logger.debug("updateAccountStatusFromDocument: no profileURL: " + ex);
- }
- } else {
- // Since some login landing pages don't have account info on them that we
- // can detect, we can try seeing if there's a session cookie stored as a
- // temp password entry. (This is a hack.)
- var sessionValue = this.acUtils.getCookie("http://piczo.com",
- gStrings["sessioncookie"]);
- if (!sessionValue) {
- sessionValue = this.acUtils.getCookie("http://www.piczo.com",
- gStrings["sessioncookie"]);
- }
- var pw = this.acUtils.getTempPassword("piczo:session:"+sessionValue);
- if (pw) {
- _logger.debug("Sneaky! Got acctID from a temp password associated with session cookie!");
- accountID = pw.user;
- }
- }
- if (accountID && accountID.length) {
- var accountURN = this.acUtils.getAccountURNById(this.urn, accountID);
- if (accountURN) {
- var c_acct = this._coop.get(accountURN);
- var results2 = getCompTK().newResults();
- if (this.webDetective.detect("piczo", "avatar", aDocument, results2)) {
- c_acct.avatar = results2.getPropertyAsAString("avatarURL");
- }
- if (!c_acct.isAuthenticated) {
- var acct = this.getAccount(accountURN);
- acct.activate(null);
- // Assume the API login will succeed. The listener should handle any
- // failures...
- c_acct.isAuthenticated = true;
- }
- if (profileURL && profileURL.length) {
- c_acct.URL = profileURL;
- }
- }
- }
- }
- }
- // END flockIManageableWebService interface
-
- ///////////////////////////////////////
- // BEGIN flockIPollingService interface
- ///////////////////////////////////////
- piczoService.prototype.refresh =
- function piczoService_refresh(aURN, aPollingListener)
- {
- _logger.info("{flockIPollingService}.refresh('" + aURN + "')");
- aPollingListener.onResult();
- }
- // END flockIPollingService interface
-
-
- piczoService.prototype.init =
- function piczoService_init()
- {
- var _logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger);
- _logger.init("piczoservice");
-
- _logger.info(".init()");
-
- // Prevent re-entry
- if (this.mIsInitialized) return;
- this.prefService = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- if (this.prefService.getPrefType(SERVICE_ENABLED_PREF) &&
- !this.prefService.getBoolPref(SERVICE_ENABLED_PREF))
- {
- _logger.info("Pref " + SERVICE_ENABLED_PREF + " set to FALSE... not initializing.");
- var catMgr = Cc["@mozilla.org/categorymanager;1"]
- .getService(Ci.nsICategoryManager);
- catMgr.deleteCategoryEntry( "wsm-startup", CATEGORY_COMPONENT_NAME, true );
- catMgr.deleteCategoryEntry( "flockWebService", CATEGORY_ENTRY_NAME, true );
- catMgr.deleteCategoryEntry("flockMediaProvider", CATEGORY_ENTRY_NAME, true);
- return;
- }
- this.mIsInitialized = true;
-
- // Initialize API
- this.mAPI = new piczoAPI();
- gAPI = this.mAPI;
- gAPI.defAlbum = {};
-
- // Init global service handle
- gSVC = this;
-
- // Initialize Coop, service and actions
- this._coop = Components.classes["@flock.com/singleton;1"]
- .getService(Components.interfaces.flockISingleton)
- .getSingleton("chrome://flock/content/common/load-faves-coop.js")
- .wrappedJSObject;
-
- this.urn = "urn:piczo:service";
- this.c_svc = new this._coop.Service(
- this.urn, {
- name: CLASS_NAME,
- desc: CLASS_DESC,
- serviceId: CONTRACT_ID,
- contactLabel: "Friends"
- }
- );
-
- // Load Web Detective and update strings
- this.webDetective = this.acUtils.useWebDetective("piczo.xml");
- for (var s in gStrings) {
- gStrings[s] = this.webDetective.getString("piczo", s, gStrings[s]);
- }
- this.url = gStrings["mainpage"];
- this.domains = gStrings["domains"];
- this.c_svc.domains = gStrings["domains"];
- this.icon = gStrings["favicon"];
- this.c_svc.loginURL = gStrings["userlogin"];
-
- // Update account auth states
- if (this.webDetective.detectCookies("piczo", "loggedout", null)) {
- this.acUtils.markAllAccountsAsLoggedOut(CONTRACT_ID);
- } else {
- var acctURN = this.acUtils.getFirstAuthenticatedAccountForService(CONTRACT_ID);
- try {
- if (acctURN) {
- var acct = this.getAccount(acctURN);
- acct.activate(null);
- }
- } catch(e) {
- _logger.info(".init() ERROR: " + e);
- }
- }
- }
-
- // ========== END piczoService class ==========
-
- // ============================================================================================================================
- // ========== BEGIN piczoAPI class ============================================================================================
- // ============================================================================================================================
-
- function piczoAPI()
- {
- _logger.info("[piczoAPI] CONSTRUCTOR");
- this.mAPIToken = null;
- this.mAPITokenID = null;
- this.mSession = {
- token: null,
- userGUID: null,
- username: null,
- password: null
- };
- this.mTS = 0;
- this.cryptoHash = Components.classes["@mozilla.org/security/hash;1"]
- .createInstance(Components.interfaces.nsICryptoHash);
- }
-
- piczoAPI.prototype.getAuthUser =
- function() {
- return this.mSession;
- }
-
- piczoAPI.prototype.QueryInterface = function(iid) {
- if (!iid.equals(Ci.nsIClassInfo) &&
- !iid.equals(Ci.nsISupports)) {
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- return this;
- }
-
- piczoAPI.prototype.getTS =
- function piczoAPI_getTS()
- {
- return (this.mTS++);
- }
-
- piczoAPI.prototype.call =
- function piczoAPI_call(aMethod, aURL, aCustomHeaders, aPostVars, aListener, aSign)
- {
- aMethod = aMethod.toUpperCase();
- _logger.debug("[piczoAPI].call('" + aMethod + "', '" + aURL + "')");
- var hr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1']
- .createInstance(Components.interfaces.nsIXMLHttpRequest);
- hr.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
- hr.open(aMethod, aURL, true);
- if (aMethod == "POST") {
- hr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded", false);
- }
- // Per Bug #9373, Piczo API chokes on '+' characters in post vars, so we
- // need this function to explicitly encode them.
- var customEscape = function piczoAPI_customEscape(aText) {
- return escape(aText).replace("+", "%2B");
- };
- if (aSign) {
- // Need to compose message string and generate signature
- var url = aURL;
- var params = [];
- var qmIdx = url.indexOf("?");
- if (qmIdx > -1) {
- var qString = url.substring(qmIdx + 1);
- url = url.substring(0, qmIdx);
- var qArr = qString.split("&");
- for (var i = 0; i < qArr.length; i++) {
- var prm = qArr[i].split("=");
- params.push([prm[0], prm[1]]);
- }
- }
- if (aCustomHeaders) {
- for (var h in aCustomHeaders) {
- params.push([h, aCustomHeaders[h]]);
- }
- }
- if (aPostVars) {
- for (var p in aPostVars) {
- params.push([p, aPostVars[p]]);
- }
- }
- params.sort();
-
- ////////////////////////////////////////////////////////
- // Piczo Digital Signature format:
- // ds := base-64( md5( {api-token} + {access-token} ) )
- ////////////////////////////////////////////////////////
- var apitoken = "";
- var accesstoken = "";
- for (var i = 0; i < params.length; i++) {
- if(params[i][0] == "at") {
- accesstoken = params[i][1];
- } else if(params[i][0] == "api-token") {
- apitoken = params[i][1];
- }
- }
- var msg = apitoken + accesstoken;
- var msgArr = [];
- for (var i = 0; i < msg.length; i++) {
- msgArr.push(msg.charCodeAt(i));
- }
- this.cryptoHash.init(Components.interfaces.nsICryptoHash.MD5);
- this.cryptoHash.update(msgArr, msgArr.length);
- var sig = this.cryptoHash.finish(true);
- var dsValue = escape(sig);
- dsValue = dsValue.replace(/\+/g,"%2B");
- dsValue = dsValue.replace(/\//g,"%2F");
- dsValue = dsValue.replace(/\@/g,"%40");
- _logger.debug("message: " + msg + " sig: " + dsValue);
- hr.setRequestHeader("ds", dsValue);
- }
- if (aCustomHeaders) {
- for (var h in aCustomHeaders) {
- var val = escape(aCustomHeaders[h]);
- val = val.replace(/\+/g,"%2B");
- val = val.replace(/\//g,"%2F");
- val = val.replace(/\@/g,"%40");
- hr.setRequestHeader(h, val);
- }
- }
- hr.onreadystatechange = function (aEvent) {
- _logger.debug("[piczoAPI].call(): hr.onreadystatechange(): " + hr.readyState);
- if (aListener) {
- if (hr.readyState == 4) {
- try {
- if (hr.status/100 == 2) {
- try {
- aListener.onSuccess(hr, aURL);
- } catch (ex) {
- _logger.info(ex);
- aListener.onError(hr, aURL, null);
- }
- } else {
- // HTTP error
- var err = {
- errorCode: hr.status,
- errorString: "HTTP error."
- };
- aListener.onError(hr, aURL, err);
- }
- } catch (ex) {
- _logger.info(ex);
- var err = {
- errorCode: Components.interfaces.flockIError.PHOTOSERVICE_UNAVAILABLE,
- errorString: "Request did not complete."
- };
- aListener.onError(hr, aURL, err);
- }
- }
- }
- };
- var postBody = "";
- if (aPostVars) {
- for (var v in aPostVars) {
- if (postBody.length) { postBody += "&"; }
- postBody += v + "=" + customEscape(aPostVars[v]);
- }
- }
- if ((aMethod == "POST") && postBody && postBody.length) {
- hr.send(postBody);
- } else {
- hr.send(null);
- }
- }
-
- piczoAPI.prototype.getAPIToken =
- function piczoAPI_getAPIToken(aListener)
- {
- _logger.debug("[piczoAPI].getAPIToken()");
- var api = this;
- var setupListener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.debug("[piczoAPI].getAPIToken() setupListener.onSuccess()");
- _logger.debug(aSubject.responseText);
- var xmlDoc = aSubject.responseXML;
- var replyEl = xmlDoc.getElementsByTagName("setup.reply").item(0);
- var tokenEl = replyEl.getElementsByTagName("api-token").item(0);
- var tokenIDEl = replyEl.getElementsByTagName("id").item(0);
- api.mAPIToken = tokenEl.childNodes.item(0).nodeValue;
- api.mAPITokenID = tokenIDEl.childNodes.item(0).nodeValue;
- _logger.debug(" got API token ID:" + api.mAPITokenID);
- _logger.debug(" got API token: "+api.mAPIToken);
- if (aListener) { aListener.onSuccess(aSubject, aTopic); }
- },
- onError: function (aSubject, aTopic, aError) {
- _logger.info("[piczoAPI].getAPIToken() setupListener.onError()");
- if (aError) {
- for (var p in aError) {
- _logger.info("error[" + p + "] = " + aError[p]);
- }
- }
- for (var p in aSubject) {
- _logger.debug("response[" + p + "] = " + aSubject[p]);
- }
- if (aListener) { aListener.onError(aSubject, aTopic, aError); }
- }
- };
- var url = gStrings["api-setup-URL"].replace("%agent%", gStrings["api-agent-string"]);
- var postVars = {
- "api-agent": gStrings["api-agent-string"]
- };
- this.call("post", url, null, postVars, setupListener);
- }
-
- piczoAPI.prototype.getPhotosCall =
- function piczoService_authenticatedGetPhotosCall(aListener, aMethod, aDictionary)
- {
- var api = this;
- api.pageID = null;
- api.pageToFind = aDictionary.albumlabel;
-
- _logger.debug("piczoService_authenticatedCall " + aMethod);
- if (!this.isLoggedIn) {
- _logger.debug("not logged in, so trying unauth call for " + aMethod);
- return this.call(aListener, aMethod, aDictionary);
- }
-
- var pageToFind = aDictionary.albumlabel;
-
- var callGetPhotos = function () {
- var url = "http://api.piczo.com/api-1/lookup";
-
- if (api.pageID) {
- url += "/" + api.pageID;
- }
-
- url += "/images?reply=rss";
-
- var headers = {
- "api-token": this.gAPI.mAPIToken,
- "at": this.gAPI.mSession.token
- };
- api.call("get", url, headers, null, aListener, true);
- };
-
- var pagesListener = {
- onSuccess: function pagesListener_onSuccess(aSubject, aTopic) {
- var xml = aSubject.responseXML;
- _logger.debug("[piczoAPI].getPages returned: "
- + aSubject.responseText);
-
- var items = xml.getElementsByTagName("item");
-
- for (var i = 0; i < items.length; i++) {
- var guid = items[i].getElementsByTagName("guid")[0]
- .firstChild.nodeValue;
- var pagelabel = items[i].getElementsByTagName("description")[0]
- .firstChild.nodeValue;
-
- if (api.pageToFind == pagelabel) {
- api.pageID = guid;
- }
- }
-
- callGetPhotos();
- return;
- },
- onError: function pagesListener_onError(aSubject, aTopic, aFlockError) {
- _logger.error("Error getting pages" + aFlockError.errorString);
- if (api.handleStaleToken(aSubject)) {
- // Resubmit the request with the new token
- api.getPhotosCall(aListener, "piczo.photos.get", aDictionary);
- } else {
- aListener.onError(aFlockError);
- }
- }
- };
-
- // Get Page ID first
- var callGetPages = function callGetPages_function() {
- var url = "http://api.piczo.com/api-1/lookup/pages?reply=rss";
-
- var headers = {
- "api-token": this.gAPI.mAPIToken,
- "at": this.gAPI.mSession.token
- };
- api.call("get", url, headers, null, pagesListener, true);
- }
-
- if (this.mAPIToken) {
- _logger.info("piczoService Calling getphotos");
- if (pageToFind != null) {
- callGetPages();
- } else {
- callGetPhotos();
- }
- } else {
- _logger.info("piczoService wasnt logged in....");
- // We are not logged in, force user to log in now.
- var aError = Cc['@flock.com/error;1'].createInstance(Ci.flockIError);
- aError.errorCode = Ci.flockIError.PHOTOSERVICE_USER_NOT_LOGGED_IN;
- aListener.onError(aError);
- }
- }
-
- piczoAPI.prototype.getAccountStatus =
- function piczoAPI_getAccountStatus(aListener) {
- _logger.info("[piczoAPI].getAccountStatus");
- }
-
- /**
- * getAlbums
- * @see flockIMediaWebService#getAlbums
- */
- piczoAPI.prototype.getAlbums =
- function piczoAPI_getAlbums(aListener, aParams) {
- _logger.info("[piczoAPI].getAlbums('" + aParams + "')");
-
- var api = this;
- var pagesListener = {
- onSuccess: function pagesListener_onSuccess(aSubject, aTopic) {
- var xml = aSubject.responseXML;
- _logger.debug("[piczoAPI].getPages returned: "
- + aSubject.responseText);
-
- var photoAlbums = [];
-
- var items = xml.getElementsByTagName("item");
-
- for (var i = 0; i < items.length; i++) {
- var guid = items[i].getElementsByTagName("guid")[0]
- .firstChild.nodeValue;
- var pagelabel = items[i].getElementsByTagName("description")[0]
- .firstChild.nodeValue;
- var newAlbum = Cc[FLOCK_PHOTO_ALBUM_CONTRACTID]
- .createInstance(Ci.flockIPhotoAlbum);
-
- newAlbum.id = guid;
- newAlbum.title = pagelabel;
-
- if (!gAPI.defAlbum.id) {
- gAPI.defAlbum = newAlbum;
- }
-
- photoAlbums.push(newAlbum);
- }
-
- var albumsEnum = {
- hasMoreElements: function() {
- return (photoAlbums.length > 0);
- },
- getNext: function() {
- return photoAlbums.shift();
- }
- }
-
- aListener.onResult(albumsEnum, null);
- },
- onError: function pagesListener_onError(aSubject, aTopic, aFlockError) {
- _logger.error("Error getting pages" + aFlockError.errorString);
- if (api.handleStaleToken(aSubject)) {
- // Resubmit the request with the new token
- api.getAlbums(aListener, "piczo.photos.get", aDictionary);
- } else {
- aListener.onError(aFlockError);
- }
- }
- };
-
- // Get Page ID first
- var callGetPages = function callGetPages_function() {
- var url = "http://api.piczo.com/api-1/lookup/pages?reply=rss";
-
- var headers = {
- "api-token": this.gAPI.mAPIToken,
- "at": this.gAPI.mSession.token
- };
- api.call("get", url, headers, null, pagesListener, true);
- }
-
- if (this.mAPIToken) {
- _logger.debug("piczoService Calling getInbox");
- callGetPages();
- } else {
- _logger.debug("piczoService wasnt logged in....");
- // We are not logged in, force user to log in now.
- var aError = Cc['@flock.com/error;1'].createInstance(Ci.flockIError);
- aError.errorCode = Ci.flockIError.PHOTOSERVICE_USER_NOT_LOGGED_IN;
- aListener.onError(aError);
- }
- }
-
- /**
- * getAlbumsForUpload
- * @see flockIMediaWebService#getAlbumsForUpload
- */
- piczoAPI.prototype.getAlbumsForUpload =
- function piczoAPI_getAlbumsForUpload(aListener, aParams) {
- _logger.debug("[piczoAPI].getAlbumsForUpload('" + aParams + "')");
-
- var api = this;
-
- // Make inbox call
- //
- var listener = {
- onSuccess: function(aSubject, aTopic) {
- //try {
- var xml = aSubject.responseXML;
- _logger.debug("[piczoAPI].getInbox returned: " + aSubject.responseText);
- var destinations = xml.getElementsByTagName("destination");
-
- var photoAlbums = [];
- _logger.debug("[piczoAPI].getInbox parsing data: " + destinations.length);
-
- gAPI.defAlbum = {};
-
- for (var i = 0; i < destinations.length; i++) {
- var name = destinations[i].getElementsByTagName('name')[0].firstChild.nodeValue;
- var uri = destinations[i].getElementsByTagName('action-uri')[0].firstChild.nodeValue;
-
- _logger.debug("[piczoAPI].getInbox data: " + name + ", " + uri);
-
- var newAlbum = Components.classes[FLOCK_PHOTO_ALBUM_CONTRACTID]
- .createInstance(Ci.flockIPhotoAlbum);
- newAlbum.id = uri;
- newAlbum.title = name;
-
- if(!gAPI.defAlbum.id) {
- gAPI.defAlbum = newAlbum;
- }
-
- photoAlbums.push(newAlbum);
- }
-
- var enum_ = {
- hasMoreElements: function() {
- return (photoAlbums.length > 0);
- },
- getNext: function() {
- return photoAlbums.shift();
- }
- }
-
- _logger.debug("[piczoAPI].getInbox returning results...");
- aListener.onResult(enum_, null);
- },
- onError: function(aSubject, aTopic, aFlockError) {
- _logger.info('Error getting inbox' + aFlockError.errorString);
- if (api.handleStaleToken(aSubject)) {
- // Resubmit the request with the new token
- api.getAlbumsForUpload(aListener, aParams);
- } else {
- aListener.onError(aFlockError);
- }
- }
- };
-
- var callGetInbox = function () {
- var url = "http://api.piczo.com/api-1/inbox" + "/images";
-
- var headers = {
- "api-token": this.gAPI.mAPIToken,
- "at": this.gAPI.mSession.token
- };
- api.call("get", url, headers, null, listener, true);
- };
-
-
- if (this.mAPIToken) {
- _logger.info("piczoService Calling getInbox");
- callGetInbox();
- } else {
- _logger.info("piczoService wasnt logged in....");
- // We are not logged in, force user to log in now.
- var aError = Cc['@flock.com/error;1'].createInstance(Ci.flockIError);
- aError.errorCode = Ci.flockIError.PHOTOSERVICE_USER_NOT_LOGGED_IN;
- aListener.onError(aError);
- return;
- }
- }
-
- // Handle the case where the session token goes stale
- // If stale reset and return true, otherwise return false
- piczoAPI.prototype.handleStaleToken =
- function(aSubject) {
-
- // When a session token goes stale the piczo api
- // marks the response with an http error (401 - unauthorized)
- // and includes error information with a new session token
-
- _logger.debug("handleStaleToken()");
- var api = this;
- if (aSubject.status == 401) {
- var xml = aSubject.responseXML;
- _logger.debug(aSubject.responseText);
-
- var errorEl = xml.getElementsByTagName("errors").item(0);
- if (!errorEl || (errorEl.length == 0)) {
- return false;
- }
-
- var invalidCrdntlEl = errorEl.getElementsByTagName("error.invalid-credential").item(0);
- if (!invalidCrdntlEl || (invalidCrdntlEl.length == 0)) {
- return false;
- }
-
- var arglinkEl = invalidCrdntlEl.getElementsByTagName("argument").item(0);
- if (!arglinkEl || (arglinkEl.length == 0)) {
- return false;
- }
-
- var problem = arglinkEl.getAttribute("problem");
- if (!problem) {
- return false;
- }
-
- _logger.debug("problem = " + problem);
- if (problem == "expired-access") {
- // Our access token went stale so grab the new one from the response
- var sessiontokenEl = errorEl.getElementsByTagName("at").item(0);
- var sessiontoken = sessiontokenEl.childNodes.item(0).nodeValue;
- _logger.debug("new access token = " + sessiontoken);
- api.mSession.token = sessiontoken;
- return true;
- }
- }
- return false;
- }
-
- piczoAPI.prototype.getPhotos =
- function piczoAPI_getPhotos(aListener, aParams) {
- _logger.debug("[piczoAPI].getPhotos('" + aParams + "')");
- var api = this;
- var listener = {
- onSuccess: function(aSubject, aTopic) {
- var photos = [];
- _logger.debug("[piczoAPI].getPhotos returned: " + aSubject.responseText);
- var xml = aSubject.responseXML;
-
- var photoList = xml.getElementsByTagName("item");
- for (var i = 0; i < photoList.length; i++) {
- var photo = photoList[i];
-
- var id = photo.getElementsByTagName('guid')[0].firstChild.nodeValue;
- var link = photo.getElementsByTagName('link')[0].firstChild.nodeValue;
- var description = photo.getElementsByTagName('description')[0].firstChild.nodeValue;
- var thumbnail = photo.getElementsByTagName("thumbnail")
- .item(0)
- .getAttribute("url");
-
- var newPhoto = new piczoPhoto();
- newPhoto.webPageUrl = link;
- newPhoto.thumbnail = link;
- newPhoto.midSizePhoto = thumbnail;
- newPhoto.largeSizePhoto = link;
- newPhoto.title = description;
- newPhoto.id = id;
- newPhoto.is_public = true;
- newPhoto.is_video = false;
-
- photos.unshift(newPhoto);
- }
-
- aListener.onSuccess(createEnum(photos), 'success');
- },
- onError: function(aSubject, aTopic, aFlockError) {
- if(aFlockError) {
- _logger.info('Error getting photos' + aFlockError.errorString);
- } else {
- _logger.info("Error getting photos");
- }
-
- if (api.handleStaleToken(aSubject)) {
- // Resubmit the request with the new token
- api.getPhotos(aListener,aParams);
- } else {
- aListener.onError(aFlockError);
- }
- }
- };
-
- var params = {
- subj_id: aParams.getPropertyAsAString("subj_id"),
- albumlabel: aParams.getPropertyAsAString("albumlabel")
- };
-
- _logger.info("calling getphotoscall");
- api.getPhotosCall(listener, 'piczo.photos.get', params);
- }
-
- piczoAPI.prototype.login =
- function piczoAPI_login(aUsername, aPassword, aListener)
- {
- _logger.debug("[piczoAPI].login('" + aUsername + "')");
- var api = this;
- if (aUsername) { this.mSession.username = aUsername; }
- if (aPassword) { this.mSession.password = aPassword; }
-
- var loginListener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.info("[piczoAPI].login() loginListener.onSuccess()");
- _logger.debug(aSubject.responseText);
- var xmlDoc = aSubject.responseXML;
- var replyEl = xmlDoc.getElementsByTagName("login.reply").item(0);
- var userlinkEl = replyEl.getElementsByTagName("user.id").item(0);
- api.mSession.userGUID = userlinkEl.getAttribute("guid");
- _logger.debug(" got user GUID: "+api.mSession.userGUID);
- var sessiontokenEl = replyEl.getElementsByTagName("at").item(0);
- api.mSession.token = sessiontokenEl.childNodes.item(0).nodeValue;
- _logger.debug(" got session token: "+api.mSession.token);
-
- if (aListener) { aListener.onSuccess(aSubject, aTopic); }
- },
- onError: function (aSubject, aTopic, aError) {
- _logger.info("[piczoAPI].login() loginListener.onError()");
- if (aListener) { aListener.onError(aSubject, aTopic, aError); }
- }
- };
-
- var callLogin = function () {
- var url = gStrings["api-login-URL"];
- var headers = {
- "ts": api.getTS()
- };
- var postVars = {
- "user-name": api.mSession.username,
- "user-password": api.mSession.password,
- "id": api.mAPITokenID,
- "api-token": api.mAPIToken
- };
- api.call("post", url, headers, postVars, loginListener);
- };
-
- if (this.mAPIToken) {
- callLogin();
- } else {
- // Need to get an API token before we can log in
- var tokenListener = {
- onSuccess: function (aSubject, aTopic) {
- callLogin();
- },
- onError: function (aSubject, aTopic, aError) {
- if (aListener) { aListener.onError(aSubject, aTopic, aError); }
- }
- };
- this.getAPIToken(tokenListener);
- }
- }
-
- piczoAPI.prototype.logout =
- function piczoAPI_logout()
- {
- _logger.info("[piczoAPI].logout()");
- this.mSession = [];
-
- var api = this;
-
- var logoutListener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.info("[piczoAPI].logout() logoutListener.onSuccess()");
- _logger.debug(aSubject.responseText);
- var xmlDoc = aSubject.responseXML;
- var replyEl = xmlDoc.getElementsByTagName("logout.reply").item(0);
- },
- onError: function (aSubject, aTopic, aError) {
- _logger.info("[piczoAPI].logout() logoutListener.onError()");
- }
- };
-
- var callLogout = function () {
- var url = gStrings["api-logout-URL"];
- var headers = {
- "ts": api.getTS()
- };
- var postVars = {
- "user-name": api.mSession.username,
- "user-password": api.mSession.password,
- "id": api.mAPITokenID,
- "api-token": api.mAPIToken
- };
- api.call("post", url, headers, postVars, logoutListener);
- };
-
- if (this.mAPIToken) {
- callLogout();
- } else {
- // Need to get an API token before we can log out
- var tokenListener = {
- onSuccess: function (aSubject, aTopic) {
- callLogout();
- },
- onError: function (aSubject, aTopic, aError) {
- if (aListener) { aListener.onError(aSubject, aTopic, aError); }
- }
- };
- this.getAPIToken(tokenListener);
- }
- }
-
- piczoAPI.prototype.upload =
- function piczoAPI_upload(aListener, aPhoto, aParams, aUpload) {
- _logger.info("piczoAPI_upload");
- // XXX: TODO
- var inst = this;
- this.uploader = new PhotoUploader();
- var myListener = {
- onResult: function(aXML) {
- _logger.debug("piczoAPI_upload: Got a result back from uploader: " + aXML.responseText);
- aListener.onUploadComplete(aUpload);
- },
- onError: function(aErrorCode) {
- _logger.info("piczoAPI_upload: " + aErrorCode);
- aListener.onError(aErrorCode);
- },
- onProgress: function(aCurrentProgress) {
- _logger.info("piczoAPI_upload: Progress");
- aListener.onProgress(aCurrentProgress);
- }
- }
- gAPI.convertBools(aParams);
- gAPI.convertTags(aParams);
-
- var dsvalue = this.getDSValue();
-
- // Check for default album seleciton
- if(!aUpload.album) {
- // auto-select the first album
- aUpload.album = gAPI.defAlbum.id;
- }
-
- this.uploader.setEndpoint(aUpload.album + "&ds=" + dsvalue);
- this.uploader.upload(myListener, aPhoto, aParams);
- }
-
- piczoAPI.prototype.getDSValue =
- function piczAPI_getDSValue() {
- _logger.info("piczoAPI_getDSValue");
- var msg = gAPI.mAPIToken + gAPI.mSession.token;
- var msgArr = [];
- for (var i = 0; i < msg.length; i++) {
- msgArr.push(msg.charCodeAt(i));
- }
- this.cryptoHash.init(Components.interfaces.nsICryptoHash.MD5);
- this.cryptoHash.update(msgArr, msgArr.length);
- var sig = this.cryptoHash.finish(true);
- var dsValue = escape(sig);
- dsValue = dsValue.replace(/\+/g,"%2B");
- dsValue = dsValue.replace(/\//g,"%2F");
- dsValue = dsValue.replace(/\@/g,"%40");
-
- return dsValue;
- }
-
- piczoAPI.prototype.convertBools =
- function piczoAPI_convertBools(aParams) {
- for (var p in aParams) {
- if (!p.match(/^is/)) continue;
- // I hope that this doesn't break anything
- if (aParams[p]=="true") aParams[p] = "1";
- if (aParams[p]=="false") aParams[p] = "0";
- }
- }
-
- piczoAPI.prototype.convertTags =
- function piczoAPI_convertTags(aParams) {
- for (var p in aParams) {
- if (p != "tags") continue;
- var tags = aParams[p].split(",");
- for (var i = 0; i < tags.length;++i) {
- tags[i] = '"' + tags[i] + '"';
- tags[i] = tags[i].replace(/\"+/g,'"');
- }
- aParams[p] = tags.join(",");
- }
- }
-
- piczoAPI.prototype.isLoggedIn =
- function piczoAPI_isLoggedIn()
- {
- return (this.mSession.token && this.mSession.token.length);
- }
-
- piczoAPI.prototype.handleDragDrop =
- function piczoAPI_handleDragDrop(url, locX, locY) {
- _logger.info("piczoAPI_handleDragDrop: " + url + ", " + locX + ", " + locY);
- // http://server/go/placeimage
- // parameters:
- // imgid (Image Id)
- // pageid (Destination page id)
- // sl (x position)
- // st (y position)
-
- // Make sure we are logged in
- // Hack it up
- var imageID;
- var results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- if (gSVC.webDetective.detectNoDOM("piczo", "piczoImageID", null, url, results)) {
- imageID = results.getPropertyAsAString("imageID");
- }
-
- var currTab;
- // Get active tab
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
- var win = wm.getMostRecentWindow('navigator:browser');
- if (win) {
- var gBrowser = win.gBrowser;
-
- for(var i=0;i<gBrowser.mTabs.length;i++) {
- var browser = gBrowser.mTabs[i].linkedBrowser;
-
- if(browser.currentURI.spec == gBrowser.currentURI.spec) {
- // We found the activce tab
- currTab = browser;
- }
- }
- }
-
- // Get active tab's top-level document
- _logger.debug("piczoAPI: document: " + currTab.contentDocument);
- var theDoc = currTab.contentDocument;
-
- // Make sure we're in a piczo edit page
- results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- if (!gSVC.webDetective.detect("piczo", "piczoedit", theDoc, results)) {
- // not a piczo edit page, return.
- _logger.info("[piczoAPI] handleDragDrop() - Not a piczo edit page");
- return false;
- }
-
- const PAGEID_STR = "pageid";
- var serverLoc;
- var loc = currTab.currentURI.spec;
- if(loc.match(/:\/\/([^\/]*)\//)) {
- serverLoc = RegExp.$1;
- }
-
- _logger.debug("piczoAPI: ServerLoc = " + serverLoc);
-
- // Get array of top-level documents' immediate children documents (sub-frames)
- var frames = theDoc.getElementsByTagName('frame');
- var iframes = theDoc.getElementsByTagName('iframe');
-
- // apply webdetective rule to each document and grab pageid
- var frameFound = null;
- var pageID = null;
- results = Components.classes["@mozilla.org/hash-property-bag;1"]
- .createInstance(Components.interfaces.nsIWritablePropertyBag2);
- for (var i = 0; i < frames.length; i++) {
- if (gSVC.webDetective.detect("piczo", "webedit", frames[i].contentDocument, results)) {
- pageID = results.getPropertyAsAString(PAGEID_STR);
- frameFound = frames[i];
- break;
- }
- }
- for (var i = 0; i < iframes.length && !frameFound; i++) {
- if (gSVC.webDetective.detect("piczo", "webedit", iframes[i].contentDocument, results)) {
- pageID = results.getPropertyAsAString(PAGEID_STR);
- frameFound = iframes[i];
- break;
- }
- }
- _logger.debug("piczoAPI: pageid=" + pageID);
-
- // Setup the url
- var aURL = "http://" + serverLoc
- + "/go/placeimage?imgid=" + imageID
- + "&pageid=" + pageID
- + "&sl=" + locX
- + "&st=" + locY;
-
- // Handler for response.
- var listener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.info("[piczoAPI].handleDragDrop() handleDragDropListener.onSuccess()");
- _logger.debug("page frame before string mangling: " + frameFound.src);
-
- // need to do a little string mangling to fool the service to reload a
- // child frame instead of the parent page
- // pass in the child frame pageid and reload
- var re = /pageid=\d+/;
- frameFound.src = frameFound.src.replace(re, PAGEID_STR + "=" + pageID);
-
- _logger.debug("page frame after string mangling: " + frameFound.src);
- return true;
- },
- onError: function (flockError) {
- return false;
- }
- }
-
- // Make simple xmlhttprequest to "move" the image to the right location
- var hr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1']
- .createInstance(Components.interfaces.nsIXMLHttpRequest);
- hr.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
- hr.onreadystatechange = function (aEvent) {
- _logger.debug("[piczoAPI].call(): hr.onreadystatechange for Moving URL: "+hr.readyState);
- if (listener) {
- if (hr.readyState == 4) {
- try {
- if (hr.status/100 == 2) {
- try {
- listener.onSuccess(hr, aURL);
- } catch (ex) {
- _logger.debug(ex);
- listener.onError(null);
- }
- } else {
- // HTTP error
- listener.onError(null);
- }
- } catch (ex) {
- _logger.info(ex);
- var err = {
- errorCode: Components.interfaces.flockIError.PHOTOSERVICE_UNAVAILABLE,
- errorString: "Request did not complete."
- };
- listener.onError(err);
- }
- }
- }
- };
- hr.open("GET", aURL, true);
- hr.send(null);
-
- // We are returning true at this point because we made it to the send() call,
- // but we won't know if the send actually succeeded because it is being called
- // asynchronously (and cannot be called synchronously, as we need to use the
- // callbacks).
- return true;
- }
-
- piczoAPI.prototype.getFriends =
- function piczoAPI_getFriends(aListener)
- {
- _logger.info("[piczoAPI].getFriends()");
- var api = this;
-
- var getNodeSubvalue = function (aNode) {
- var longest = "";
- for (var i = 0; i < aNode.childNodes.length; i++) {
- var item = aNode.childNodes.item(i);
- if (item.nodeValue.length > longest.length) {
- longest = item.nodeValue;
- }
- }
- return longest;
- };
-
- var friendsListener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.info("[piczoAPI].getFriends() friendsListener.onSuccess()");
- _logger.debug(aSubject.responseText);
- var replyEl = aSubject.responseXML.getElementsByTagName("lookup.reply").item(0);
- var friendsEl = replyEl.getElementsByTagName("friends").item(0);
- var friendEls = friendsEl.getElementsByTagName("friend");
- var friends = [];
- for (var i = 0; i < friendEls.length; i++) {
- var friendEl = friendEls.item(i);
- var primaryProfEl = friendEl.getElementsByTagName("primary-profile").item(0);
- var thumbEl = primaryProfEl.getElementsByTagName("thumbnail").item(0);
- var websiteEl = primaryProfEl.getElementsByTagName("website-link").item(0);
- friends.push({
- id: friendEl.getAttribute("guid"),
- name: getNodeSubvalue(friendEl.getElementsByTagName("name").item(0)),
- avatarURL: getNodeSubvalue(thumbEl.getElementsByTagName("uri").item(0)),
- URL: getNodeSubvalue(websiteEl.getElementsByTagName("uri").item(0))
- });
- }
- aListener.onSuccess(friends, aTopic);
- },
- onError: function (aSubject, aTopic, aFlockError) {
- _logger.info("[piczoAPI].getFriends() friendsListener.onError()");
- if (api.handleStaleToken(aSubject)) {
- // Resubmit the request with the new token
- callGetFriends();
- } else {
- aListener.onError(aFlockError);
- }
- }
- };
-
- var callGetFriends = function () {
- var url = gStrings["api-friends-URL"];
- var headers = {
- "ts": api.getTS(),
- "sn": api.mSession.token,
- };
- api.call("get", url, headers, null, friendsListener, true);
- };
-
- callGetFriends();
- }
-
- // ========== END piczoAPI class ==========
-
-
-
- // ==============================================
- // ========== BEGIN piczoAccount class ==========
- // ==============================================
-
- function piczoAccount()
- {
- _logger.info("piczoAccount CONSTRUCTOR");
- this.acUtils = Components.classes["@flock.com/account-utils;1"]
- .getService(Components.interfaces.flockIAccountUtils);
- this._coop = Components.classes["@flock.com/singleton;1"]
- .getService(Components.interfaces.flockISingleton)
- .getSingleton("chrome://flock/content/common/load-faves-coop.js")
- .wrappedJSObject;
- this.mAPI = gAPI;
- this._ctk = {
- interfaces: [
- "nsISupports",
- "flockIWebServiceAccount",
- "flockIMediaWebServiceAccount",
- "flockIMediaUploadAccount",
- ],
- };
- getCompTK().addAllInterfaces(this);
-
- _logger.debug("piczoAccount Constructor End.");
- }
-
- piczoAccount.prototype.urn = null;
-
- // BEGIN flockIWebServiceAccount interface
- piczoAccount.prototype.login =
- function piczoAccount_login(aListener)
- {
- var account = this;
- var c_acct = account._coop.get(account.urn);
- var loginListener = {
- onSuccess: function (aSubject, aTopic) {
- account.acUtils.ensureOnlyAuthenticatedAccount(account.urn);
- c_acct.piczo_guid = account.mAPI.mSession.userGUID;
- if (aListener) { aListener.onSuccess(aSubject, aTopic); }
- },
- onError: function (aSubject, aTopic, aError) {
- c_acct.isAuthenticated = false;
- if (aListener) { aListener.onError(aSubject, aTopic, aError); }
- }
- };
- var pw = this.acUtils.getPassword("urn:piczo:service"+':'+c_acct.accountId);
- this.mAPI.login(pw.user, pw.password, loginListener);
- }
-
- piczoAccount.prototype.logout =
- function piczoAccount_logout(aListener)
- {
- _logger.info("{flockIWebServiceAccount}.logout()");
- var c_acct = this._coop.get(this.urn);
- if (c_acct.isAuthenticated) {
- try {
- this.mAPI.logout();
- } catch (ex) {
- _logger.warn("API logout call failed with error: "+ex);
- }
- Cc[CONTRACT_ID].getService(Ci.flockIWebService).logout();
- c_acct.isAuthenticated = false;
- }
- }
-
- piczoAccount.prototype.activate =
- function piczoAccount_activate(aListener)
- {
- _logger.info("{flockIWebServiceAccount}.activate()");
- var c_acct = this._coop.get(this.urn);
- //c_acct.isTransient = false;
- var account = this;
- var loginListener = {
- onSuccess: function (aSubject, aTopic) {
- _logger.info(".activate() loginListener.onSuccess()");
- // XXX TODO FIXME: API login
- if (aListener) aListener.onSuccess(account, "accountAuthorized");
- c_acct.isPollable = true;
- account.acUtils.ensureOnlyAuthenticatedAccount(account.urn);
- },
- onError: function (aSubject, aTopic, aError) {
- _logger.info(".activate() loginListener.onError()");
- c_acct.isAuthenticated = true;
- }
- };
- //this.acUtils.makeTempPasswordPermanent(this.service.urn+':'+c_acct.accountId);
- this.login(loginListener);
- // Assume login will succeed. Listener will handle failures.
- c_acct.isAuthenticated = true;
- }
- // END flockIWebServiceAccount interface
-
- // ========== END piczoAccount class ==========
-
-
-
- // =========================================
- // ========== BEGIN XPCOM Support ==========
- // =========================================
-
- function createModule(aParams) {
- return {
- registerSelf: function (aCompMgr, aFileSpec, aLocation, aType) {
- aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
- aCompMgr.registerFactoryLocation( aParams.CID, aParams.componentName,
- aParams.contractID, aFileSpec,
- aLocation, aType );
- var catMgr = Cc["@mozilla.org/categorymanager;1"]
- .getService(Ci.nsICategoryManager);
- if (!aParams.categories) { aParams.categories = []; }
- for (var i = 0; i < aParams.categories.length; i++) {
- var cat = aParams.categories[i];
- catMgr.addCategoryEntry( cat.category, cat.entry,
- cat.value, true, true );
- }
- },
- getClassObject: function (aCompMgr, aCID, aIID) {
- if (!aCID.equals(aParams.CID)) { throw Cr.NS_ERROR_NO_INTERFACE; }
- if (!aIID.equals(Ci.nsIFactory)) { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }
- return { // Factory
- createInstance: function (aOuter, aIID) {
- if (aOuter != null) { throw Cr.NS_ERROR_NO_AGGREGATION; }
- var comp = new aParams.componentClass();
- if (aParams.implementationFunc) { aParams.implementationFunc(comp); }
- return comp.QueryInterface(aIID);
- }
- };
- },
- canUnload: function (aCompMgr) { return true; }
- };
- }
-
- // NS Module entrypoint
- function NSGetModule(aCompMgr, aFileSpec) {
- return createModule({
- componentClass: piczoService,
- CID: CLASS_ID,
- contractID: CONTRACT_ID,
- componentName: CATEGORY_COMPONENT_NAME,
- implementationFunc: function (aComp) { getCompTK().addAllInterfaces(aComp); aComp.init(); },
- categories: [
- { category: "wsm-startup", entry: CATEGORY_COMPONENT_NAME, value: CONTRACT_ID },
- { category: "flockWebService", entry: CATEGORY_ENTRY_NAME, value: CONTRACT_ID },
- { category: "flockMediaProvider", entry: CATEGORY_ENTRY_NAME, value: CONTRACT_ID }
- ]
- });
- }
-
- // ========== END XPCOM Support ==========
-